/*
 * This source code is part of TWaver 4.0
 *
 * Serva Software PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 * Copyright 2002 - 2011 Serva Software. All rights reserved.
 */

package demo.network.topo.layer;

import java.awt.BorderLayout;
import java.awt.Color;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JPanel;
import javax.swing.JSplitPane;

import twaver.DataBoxQuickFinder;
import twaver.DataBoxSelectionEvent;
import twaver.DataBoxSelectionListener;
import twaver.Element;
import twaver.EnumType;
import twaver.EnumTypeManager;
import twaver.Layer;
import twaver.Node;
import twaver.ResizableFilter;
import twaver.ResizableNode;
import twaver.TDataBox;
import twaver.TWaverConst;
import twaver.TWaverUtil;
import twaver.network.TNetwork;
import demo.DemoPane;

public class LayerDemo extends DemoPane {

	private TDataBox box = new TDataBox();
	private TNetwork network = new TNetwork(box);
	private TDataBox tableBox = new TDataBox();
	public DataBoxQuickFinder layerFinder;
	private boolean boxSelectionChange = true;
	private boolean tableBoxSelectionChange = true;

	public LayerDemo() {
		layerFinder = box.createJavaBeanFinder(TWaverConst.PROPERTYNAME_LAYERID);
		initBox();
		convertBoxToTableBox();
		initGUI();
		initNetwork();
		initBoxListener();
	}

	private void initBox() {
		Object[] gradientObj = EnumTypeManager.getInstance().getEnumTypes(TWaverConst.ENUM_GRADIENT);
		Object[] shapeObj = EnumTypeManager.getInstance().getEnumTypes(TWaverConst.ENUM_SHAPE);
		int size = shapeObj.length;
		for (int i = 0; i < size; i++) {
			EnumType shape = (EnumType) shapeObj[i];
			EnumType gradient = (EnumType) gradientObj[(int) (gradientObj.length * Math.random())];
			String layerId = shape.getValue().toString();
			Layer layer = new Layer(layerId);
			box.getLayerModel().addLayer(layer);
			layer.setAlpha((float) (((int) (Math.random() * 4)) / 10.0 + 0.7));
			layer.setName(shape.getDisplayName());
			layer.setMovable(true);
			Color gradientColor = Color.WHITE;
			Color fillColor = TWaverUtil.getRandomColor();
			boolean isGradient = true;
			String stroke = TWaverConst.STROKE_SOLID_THINNEST;
			if (i % size == 0) {
				stroke = TWaverConst.STROKE_ZIGZAG_NARROWEST;
			}
			else if (i % size == 4) {
				stroke = TWaverConst.STROKE_SQUARE_THINNEST;
			}
			else if (i % size == 7) {
				stroke = TWaverConst.STROKE_DOT_THINNEST;
			}
			else if (i % size == 11) {
				stroke = TWaverConst.STROKE_SOLID_2;
			}
			else if (i % size == 13) {
				stroke = TWaverConst.STROKE_DASH_THINNEST;
			}
			else if (i % size == 16) {
				stroke = TWaverConst.STROKE_DASH_DOT_DOT_THINNEST;
			}
			else if (i % size == 19) {
				stroke = TWaverConst.STROKE_DASH_DOT_THINNEST;
			}
			Color outlineColor = TWaverUtil.getRandomColor();
			layer.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_SHAPE_FACTORY, shape.getValue());
			layer.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT_FACTORY, gradient.getValue());
			layer.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_FILL_COLOR, fillColor);
			layer.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT, new Boolean(isGradient));
			layer.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT_COLOR, gradientColor);
			layer.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_OUTLINE_STROKE, stroke);
			layer.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_OUTLINE_COLOR, outlineColor);
			for (int j = 0; j < 4; j++) {
				ResizableNode element = new ResizableNode();
				element.setSize(80, 80);
				element.setLayerID(layerId);
				element.putCustomDraw(true);
				element.putCustomDrawShapeFactory(((Integer) (shape.getValue())).intValue());
				element.putCustomDrawGradientFactory(((Integer) (gradient.getValue())).intValue());
				element.putCustomDrawFillColor(fillColor);
				element.putCustomDrawGradient(isGradient);
				element.putCustomDrawGradientColor(gradientColor);
				element.putCustomDrawOutlineColor(outlineColor);
				element.setLocation(Math.random() * 800, Math.random() * 500);
				element.putCustomDrawOutlineStroke(stroke);
				box.addElement(element);
			}
		}
	}

	private void initGUI() {
		this.setLayout(new BorderLayout());
		this.add(network, BorderLayout.CENTER);
		JSplitPane pane = new JSplitPane(JSplitPane.VERTICAL_SPLIT);
		pane.setDividerSize(3);
		pane.setTopComponent(network);
		pane.setBottomComponent(getControlPanel());
		pane.setDividerLocation(450);
		this.add(pane, BorderLayout.CENTER);
	}

	private JPanel getControlPanel() {
		TablePanel layerManagerPane = new TablePanel(tableBox, box);
		return layerManagerPane;
	}

	private void initNetwork() {
		network.setResizableFilter(new ResizableFilter() {
			public boolean isResizable(Element element) {
				return true;
			}
		});
	}

	private void initBoxListener() {
		box.getSelectionModel().addDataBoxSelectionListener(new DataBoxSelectionListener() {
			public void selectionChanged(DataBoxSelectionEvent e) {
				if (boxSelectionChange && tableBoxSelectionChange) {
					boxSelectionChange = false;
					List list = box.getSelectionModel().getAllSelectedElement();
					int size = list.size();
					List selectList = new ArrayList();
					for (int i = 0; i < size; i++) {
						Element element = (Element) list.get(i);
						Layer layer = box.getLayerModel().getLayerByID(element.getLayerID());
						selectList.add(tableBox.getElementByID(layer));
					}
					tableBox.getSelectionModel().setSelection(selectList);
					boxSelectionChange = true;
				}
			}
		});
		tableBox.getSelectionModel().addDataBoxSelectionListener(new DataBoxSelectionListener() {
			public void selectionChanged(DataBoxSelectionEvent e) {
				if (tableBoxSelectionChange && boxSelectionChange) {
					tableBoxSelectionChange = false;
					List list = tableBox.getSelectionModel().getAllSelectedElement();
					int size = list.size();
					List selectList = new ArrayList();
					for (int i = 0; i < size; i++) {
						Element element = (Element) list.get(i);
						Layer layer = (Layer) element.getID();
						List findList = layerFinder.find(layer.getID());
						if (findList != null) {
							selectList.addAll(findList);
						}
					}
					box.getSelectionModel().setSelection(selectList);
					tableBoxSelectionChange = true;
				}
			}
		});

		tableBox.addElementPropertyChangeListener(new PropertyChangeListener() {
			public void propertyChange(PropertyChangeEvent evt) {
				Element element = (Element) evt.getSource();
				Layer layer = (Layer) element.getID();
				String name = TWaverUtil.getPropertyName(evt);
				Object newValue = evt.getNewValue();
				List findList = layerFinder.find(layer.getID());
				int size = findList.size();
				if (Layer.PROPERTY_NAME.equals(name)) {
					layer.setName(newValue.toString());
				}
				else if (Layer.PROPERTY_VISIBLE.equals(name)) {
					layer.setVisible(((Boolean) (newValue)).booleanValue());
				}
				else if (Layer.PROPERTY_SELECTABLE.equals(name)) {
					layer.setSelectable(((Boolean) (newValue)).booleanValue());
				}
				else if (Layer.PROPERTY_MOVABLE.equals(name)) {
					layer.setMovable(((Boolean) (newValue)).booleanValue());
				}
				else if (Layer.PROPERTY_RESIZABLE.equals(name)) {
					layer.setResizable(((Boolean) (newValue)).booleanValue());
				}
				else if (Layer.PROPERTY_ALPHA.equals(name)) {
					layer.setAlpha(((Float) (newValue)).floatValue());
				}
				else if (Layer.PROPERTY_DESCRIPTION.equals(name)) {
					layer.setDescription(newValue.toString());
				}
				else if (TWaverConst.PROPERTYNAME_CUSTOM_DRAW_SHAPE_FACTORY.equals(name)) {
					for (int i = 0; i < size; i++) {
						Node node = (Node) findList.get(i);
						node.putCustomDrawShapeFactory(((Integer)(newValue)).intValue());
					}
				}
				else if (TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT_FACTORY.equals(name)) {
					for (int i = 0; i < size; i++) {
						Node node = (Node) findList.get(i);
						node.putCustomDrawGradientFactory(((Integer)(newValue)).intValue());
					}
				}
				else if (TWaverConst.PROPERTYNAME_CUSTOM_DRAW_FILL_COLOR.equals(name)) {
					for (int i = 0; i < size; i++) {
						Node node = (Node) findList.get(i);
						node.putCustomDrawFillColor((Color) (newValue));
					}
				}
				else if (TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT.equals(name)) {
					for (int i = 0; i < size; i++) {
						Node node = (Node) findList.get(i);
						node.putCustomDrawGradient(((Boolean) (newValue)).booleanValue());
					}
				}
				else if (TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT_COLOR.equals(name)) {
					for (int i = 0; i < size; i++) {
						Node node = (Node) findList.get(i);
						node.putCustomDrawGradientColor((Color) (newValue));
					}
				}
				else if (TWaverConst.PROPERTYNAME_CUSTOM_DRAW_OUTLINE_STROKE.equals(name)) {
					for (int i = 0; i < size; i++) {
						Node node = (Node) findList.get(i);
						node.putCustomDrawOutlineStroke(newValue.toString());
					}
				}
				else if (TWaverConst.PROPERTYNAME_CUSTOM_DRAW_OUTLINE_COLOR.equals(name)) {
					for (int i = 0; i < size; i++) {
						Node node = (Node) findList.get(i);
						node.putCustomDrawOutlineColor((Color) (newValue));
					}
				}
			}
		});
	}

	private void convertBoxToTableBox() {
		List layers = box.getLayerModel().getLayers();
		int size = layers.size();
		for (int i = 0; i < size; i++) {
			Layer layer = (Layer) layers.get(i);
			if (layer == box.getLayerModel().getDefaultLayer()) {
				continue;
			}
			Element element = new Node(layer);
			element.putClientProperty(Layer.PROPERTY_ID, layer.getID());
			element.putClientProperty(Layer.PROPERTY_NAME, layer.getName());
			element.putClientProperty(Layer.PROPERTY_VISIBLE, layer.isVisible());
			element.putClientProperty(Layer.PROPERTY_SELECTABLE, layer.isSelectable());
			element.putClientProperty(Layer.PROPERTY_MOVABLE, layer.isMovable());
			element.putClientProperty(Layer.PROPERTY_RESIZABLE, layer.isResizable());
			element.putClientProperty(Layer.PROPERTY_ALPHA, new Float(layer.getAlpha()));
			element.putClientProperty(Layer.PROPERTY_DESCRIPTION, layer.getDescription());

			element.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_SHAPE_FACTORY, layer.getClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_SHAPE_FACTORY));
			element.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT_FACTORY, layer.getClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT_FACTORY));
			element.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT, layer.getClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT));
			element.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT_COLOR, layer.getClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_GRADIENT_COLOR));
			element.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_FILL_COLOR, layer.getClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_FILL_COLOR));
			element.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_OUTLINE_STROKE, layer.getClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_OUTLINE_STROKE));
			element.putClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_OUTLINE_COLOR, layer.getClientProperty(TWaverConst.PROPERTYNAME_CUSTOM_DRAW_OUTLINE_COLOR));
			tableBox.addElement(element);
		}

	}
}